/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Parser;
import java.util.ArrayList;

/**
 * Clasa Parser este un parser abstract a unei functii in format String.
 * Acesta va transforma stringul intr-un vector de pozitii ce va contine fiecare operator si functie.
 * @author AlinT
 */
public abstract class Parser{

   public boolean oke;
   public ArrayList<String> operatori=new ArrayList<String>(20);

   /**
    * Functia ce determina pozitia operatorului in vectorul de operatori
    * @param op Stringul considerat operator
    * @return daca argumentul functiei este sau nu in lista de operatori
    */
   public boolean isOperator(String op) { return operatori.indexOf(op) != -1; }

   /**
    * Functia abstracta ce determina precedenta operatorilor
    * @param c operatorul1 a carui precedenta se verifica
    * @param d operatorul2 a carui precedenta se verifica
    * @return true daca primul operator are precedenta mai mica decat cel de-al doilea, iar in caz contrar false
    */
   public abstract boolean hasLessPrecedence(String c, String d);

   /**
    * Funcia abstracta ce transforma vectorul de pozitii primit  in forma lui poloneza pentru a facilita punerea in arborele functional
    * @param poz vectorul de pozitii ce va fi transformat in forma poloneza
    * @return vectorul transformat in forma poloneza
    */
   public abstract ArrayList<String> polishForm(ArrayList<String> poz);

   /**
    * Functia transforma unele functii in litere mari pentru a nu fi confundate cu altele
    * @return stringul transformat in litere mari
    */
   public String replaceCapsLock(String exp){
      exp +=" ";
      exp=exp.replaceAll("exp", "EXP");
      exp=exp.replaceAll("arcsin", "ARCSIN");
      exp=exp.replaceAll("arccos", "ARCCOS");
      exp=exp.replaceAll("arcctg", "ARCCTG");
      exp=exp.replaceAll("arctg", "ARCTG");
      return exp;
   }

   /**
    * Functia ce creaza un vector ce va contine pe fiecare pozitie operatorul, operandul sau functia corespunzatoare
    * pozitiei pe care se afla in sirul de caractere initial
    * @param exp expresia ce va fi impartita intr-un vector de pozitii
    * @return vectorul ce va contine pe fiecare pozitie cate un operaor sau un operand
    */
   public ArrayList<String> createPoz(String exp)
   {
      
      ArrayList<String> poz=new ArrayList<String>(20);

      for(int ij=0; ij<20; ij++)
          poz.add(ij, "");

      int i=0; 
      exp=replaceCapsLock(exp);
      
      int q=0, k=0;
      for(int j=0; j<operatori.size(); j++){
          k=0;
          do{
              q=exp.indexOf(operatori.get(j), k);
              if(q!=-1){
               poz.set(q, operatori.get(j));}
              k = q+operatori.get(j).length();

          }while(q!=-1);
      }
 
      k=0;
      do{
              q=exp.indexOf("x", k);
              if(q!=-1){
                System.out.println(" "+q+" "+"x");
                poz.set(q, "x");}
              k = q+1;
      }while(q!=-1);

      int ii=0; String nr; int pozitie=0;
      while(ii<exp.length()){
          char c=exp.charAt(ii); nr="";
          if(c >= '0' && c <= '9'){
              pozitie=ii;
              do{
                nr += c;
                c=exp.charAt(++ii);
                if(!(c >= '0' && c <= '9')){
                    System.out.println(" "+pozitie+" "+nr);
                    poz.set(pozitie, nr);
                }
              }while(c >= '0' && c <= '9');}
          ii++;
      }

      int count = 0;
      for(int v=0;v<poz.size();v++)
          if(poz.get(v).equals(""))
              count++;

      int verification=0;
      for(int l=0;l<poz.size();l++)
      {
          String pp=poz.get(l);
          try{
              verification=Integer.parseInt(pp);
          }catch(Exception e){}
          if(pp.equals("sin") || pp.equals("cos") || pp.equals("tg") || pp.equals("ctg") ||
                  pp.equals("ARCSIN") || pp.equals("ARCCOS") || pp.equals("ARCTG") || pp.equals("ARCCTG") ||
                  pp.equals("pow") || pp.equals("EXP") || pp.equals("log") || pp.equals("sqrt") || pp.equals("/")
                  || (l==0 && verification!=0 && poz.size()-count==1) || (l==1 && verification!=0 && poz.size()-count==2))
              this.oke=false;
      }

      return polishForm(poz);
    }

}
